% Назначение: Детектор Витерби с учетом параметров канала
% Вход:       points  - точки сигнального пространства (могут быть зашумленными)
%             trel    - структура описывающая таблицу переходов используемого
%                       свёрточного кода
% Выход:      decoded - декодированные символы
% Обращение:  decoded = myvitdec(points, trel)
function decoded = myvitdec(points, trel)

k = length(points);

infMetric = Inf * ones(1, trel.numStates);

% начальное состояние
states    = zeros(trel.numStates, k);
oldMetric = infMetric;
metric    = infMetric;

permittedStates = 1; % состояния в которые можно попасть на текущем такте

for l = 1 : k
    for s = permittedStates
        for i = 1 : trel.numInputSymbols
            d = norm(trel.outputs(s, i) - points(l), 2); % Евклидова метрика
            if oldMetric(trel.nextStates(s, i) + 1) ~= Inf
                if d + oldMetric(s) < metric(trel.nextStates(s, i) + 1)
                    metric(trel.nextStates(s, i) + 1)    = d + oldMetric(s);
                    states(trel.nextStates(s, i) + 1, l) = s - 1;
                end
            elseif d < metric(trel.nextStates(s, i) + 1)
                metric(trel.nextStates(s, i) + 1)    = d;
                states(trel.nextStates(s, i) + 1, l) = s - 1;
            end
        end
    end
    permittedStates = find(metric < Inf);
    oldMetric       = metric;
    metric          = infMetric;
end

[~, s]  = min(oldMetric); % состояние с наименьшей метрикой

% поиск начала пути
decoded = zeros(k, 1);
for i = k : -1 : 1
    decoded(i, 1) = s - 1; % -1 потом +1 бред какой-то
    s = states(s, i) + 1;
end

end